import backtrader as bt
from .DbOprate import DbOprate

class HighVolumeBearishStrategy(bt.Strategy):
    
    def log(self, txt, dt=None):
        dt = dt or self.datas[0].datetime.date(0)
        print(f'{dt.isoformat()}, {txt}')

    def __init__(self):
        self.data_close = self.datas[0].close
        self.data_open = self.datas[0].open
        self.data_high = self.datas[0].high
        self.data_low = self.datas[0].low
        self.data_volume = self.datas[0].volume
        
        # 计算X_47: 高位放量阴线
        # VOL=HHV(VOL,20) AND CLOSE<OPEN AND OPEN/REF(CLOSE,1)>1.03
        self.hhv_vol_20 = bt.indicators.Highest(self.data_volume, period=20)
        self.ref_close_1 = self.data_close(-1)
        self.x_47 = bt.And(
            self.data_volume == self.hhv_vol_20,  # VOL=HHV(VOL,20)
            self.data_close < self.data_open,     # CLOSE<OPEN
            self.data_open / self.ref_close_1 > 1.03  # OPEN/REF(CLOSE,1)>1.03
        )
        
        # 计算X_48: 放量长上影阴线
        # VOL=HHV(VOL,40) AND CLOSE<OPEN AND HIGH>MAX(OPEN,CLOSE)*1.03
        self.hhv_vol_40 = bt.indicators.Highest(self.data_volume, period=40)
        self.max_open_close = bt.Max(self.data_open, self.data_close)
        self.x_48 = bt.And(
            self.data_volume == self.hhv_vol_40,      # VOL=HHV(VOL,40)
            self.data_close < self.data_open,         # CLOSE<OPEN
            self.data_high > self.max_open_close * 1.03  # HIGH>MAX(OPEN,CLOSE)*1.03
        )
        
        # 综合卖出信号
        self.sell_signal = bt.Or(self.x_47, self.x_48)
        
        self.order = None

    def next(self):
        if self.order:
            return
            
        # 卖出信号检测
        if self.sell_signal[0]:
            signal_type = None
            if self.x_47[0]:
                self.log(f'X_47信号触发! 高位放量阴线')
                self.log(f'成交量: {self.data_volume[0]}, HHV20: {self.hhv_vol_20[0]}')
                self.log(f'收盘价: {self.data_close[0]}, 开盘价: {self.data_open[0]}')
                self.log(f'开盘价/昨收盘: {self.data_open[0]/self.ref_close_1[0]:.4f}')
                signal_type = 'X_47_high_volume_bearish'
            elif self.x_48[0]:
                self.log(f'X_48信号触发! 放量长上影阴线')
                self.log(f'成交量: {self.data_volume[0]}, HHV40: {self.hhv_vol_40[0]}')
                self.log(f'收盘价: {self.data_close[0]}, 开盘价: {self.data_open[0]}')
                self.log(f'最高价: {self.data_high[0]}, MAX(OPEN,CLOSE)*1.03: {self.max_open_close[0]*1.03:.2f}')
                signal_type = 'X_48_high_volume_long_shadow'
            
            # 在HIGH*1.005位置显示蓝球图标
            icon_position = self.data_high[0] * 1.005
            self.log(f'蓝球图标位置: {icon_position:.2f}')
            
            # 记录信号到数据库（即使没有持仓也要记录）
            signal_result = {
                'strategy': 'HighVolumeBearishStrategy',
                'stock_code': self.datas[0]._name,
                'op_act': 'signal',
                'op_price': float(self.data_close[0]),
                'op_num': 0,
                'op_comm': 0.0,
                'op_dt': self.datas[0].datetime.date(0).isoformat(),
                'reason': signal_type
            }
            
            DbOprate.save_result_to_mysql(signal_result)
            
            # 如果有持仓则执行卖出操作
            if self.position:
                position_size = self.position.size
                self.log(f'执行卖出操作, 卖出数量: {position_size}')
                self.order = self.sell(size=position_size)
                
                # 保存交易记录
                trade_result = {
                    'strategy': 'HighVolumeBearishStrategy',
                    'stock_code': self.datas[0]._name,
                    'op_act': 'sell',
                    'op_price': float(self.data_close[0]),
                    'op_num': int(position_size),
                    'op_comm': 0.0,
                    'op_dt': self.datas[0].datetime.date(0).isoformat(),
                    'reason': signal_type
                }
                
                DbOprate.save_result_to_mysql(trade_result)

    def notify_order(self, order):
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(f'买入执行, 价格: {order.executed.price:.2f}')
            elif order.issell():
                self.log(f'卖出执行, 价格: {order.executed.price:.2f}')
            self.order = None
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('订单取消/保证金不足/拒绝')
            self.order = None
